package com.mmc.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.mmc.common.result.Result;
import com.mmc.entity.Menu;
import com.mmc.service.MenuService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 菜单控制器
 *
 * @author kunfe
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/menus")
@RequiredArgsConstructor
@SaCheckLogin
@Tag(name = "菜单管理", description = "菜单管理相关接口")
public class MenuController {

    private final MenuService menuService;

    @Operation(summary = "获取菜单树")
    @GetMapping("/tree")
    public Result<List<Menu>> getMenuTree() {
        List<Menu> menus = menuService.getMenuTree();
        return Result.ok(menus);
    }

    @Operation(summary = "获取当前用户菜单树")
    @GetMapping("/user-tree")
    public Result<List<Menu>> getUserMenuTree() {
        Long userId = StpUtil.getLoginIdAsLong();
        List<Menu> menus = menuService.getMenuTreeByUserId(userId);
        return Result.ok(menus);
    }

    @Operation(summary = "获取所有菜单列表")
    @GetMapping("/list")
    public Result<List<Menu>> getMenuList(
            @RequestParam(required = false) String menuName,
            @RequestParam(required = false) Integer status) {
        
        List<Menu> menus = menuService.getAllMenus(menuName, status);
        return Result.ok(menus);
    }

    @Operation(summary = "根据父菜单ID获取子菜单")
    @GetMapping("/children/{parentId}")
    public Result<List<Menu>> getMenusByParentId(@PathVariable Long parentId) {
        List<Menu> menus = menuService.getMenusByParentId(parentId);
        return Result.ok(menus);
    }

    @Operation(summary = "获取菜单详情")
    @GetMapping("/{id}")
    public Result<Menu> getMenuById(@PathVariable Long id) {
        Menu menu = menuService.getById(id);
        return Result.ok(menu);
    }

    @Operation(summary = "新增菜单")
    @PostMapping
    public Result<Void> createMenu(@Valid @RequestBody CreateMenuRequest request) {
        Menu menu = new Menu();
        menu.setParentId(request.getParentId());
        menu.setMenuName(request.getMenuName());
        menu.setMenuType(request.getMenuType());
        menu.setPath(request.getPath());
        menu.setComponent(request.getComponent());
        menu.setPermission(request.getPermission());
        menu.setIcon(request.getIcon());
        menu.setSort(request.getSort());
        menu.setIsFrame(request.getIsFrame());
        menu.setIsCache(request.getIsCache());
        menu.setVisible(request.getVisible());
        menu.setStatus(request.getStatus());
        menu.setRemark(request.getRemark());
        
        boolean success = menuService.createMenu(menu);
        return success ? Result.ok() : Result.fail("新增失败");
    }

    @Operation(summary = "更新菜单")
    @PutMapping("/{id}")
    public Result<Void> updateMenu(@PathVariable Long id, @Valid @RequestBody UpdateMenuRequest request) {
        Menu menu = new Menu();
        menu.setId(id);
        menu.setParentId(request.getParentId());
        menu.setMenuName(request.getMenuName());
        menu.setMenuType(request.getMenuType());
        menu.setPath(request.getPath());
        menu.setComponent(request.getComponent());
        menu.setPermission(request.getPermission());
        menu.setIcon(request.getIcon());
        menu.setSort(request.getSort());
        menu.setIsFrame(request.getIsFrame());
        menu.setIsCache(request.getIsCache());
        menu.setVisible(request.getVisible());
        menu.setStatus(request.getStatus());
        menu.setRemark(request.getRemark());
        
        boolean success = menuService.updateMenu(menu);
        return success ? Result.ok() : Result.fail("更新失败");
    }

    @Operation(summary = "删除菜单")
    @DeleteMapping("/{id}")
    public Result<Void> deleteMenu(@PathVariable Long id) {
        boolean success = menuService.deleteMenu(id);
        return success ? Result.ok() : Result.fail("删除失败");
    }

    @Operation(summary = "批量删除菜单")
    @DeleteMapping("/batch")
    public Result<Void> batchDeleteMenu(@Valid @RequestBody BatchDeleteRequest request) {
        boolean success = menuService.batchDeleteMenu(request.getIds());
        return success ? Result.ok() : Result.fail("删除失败");
    }

    @Operation(summary = "启用/禁用菜单")
    @PutMapping("/{id}/status")
    public Result<Void> changeStatus(@PathVariable Long id, @RequestBody ChangeStatusRequest request) {
        boolean success = menuService.changeStatus(id, request.getStatus());
        return success ? Result.ok() : Result.fail("操作失败");
    }

    @Operation(summary = "检查菜单是否有子菜单")
    @GetMapping("/{id}/has-children")
    public Result<Boolean> hasChildren(@PathVariable Long id) {
        boolean hasChildren = menuService.hasChildren(id);
        return Result.ok(hasChildren);
    }

    // DTO类
    @Data
    public static class CreateMenuRequest {
        private Long parentId = 0L;
        
        @NotBlank(message = "菜单名称不能为空")
        private String menuName;
        
        @NotNull(message = "菜单类型不能为空")
        private Integer menuType;
        
        private String path;
        private String component;
        private String permission;
        private String icon;
        private Integer sort = 0;
        private Integer isFrame = 0;
        private Integer isCache = 0;
        private Integer visible = 1;
        private Integer status = 1;
        private String remark;
    }

    @Data
    public static class UpdateMenuRequest {
        private Long parentId;
        
        @NotBlank(message = "菜单名称不能为空")
        private String menuName;
        
        @NotNull(message = "菜单类型不能为空")
        private Integer menuType;
        
        private String path;
        private String component;
        private String permission;
        private String icon;
        private Integer sort;
        private Integer isFrame;
        private Integer isCache;
        private Integer visible;
        private Integer status;
        private String remark;
    }

    @Data
    public static class BatchDeleteRequest {
        @NotEmpty(message = "删除ID列表不能为空")
        private List<Long> ids;
    }

    @Data
    public static class ChangeStatusRequest {
        @NotNull(message = "状态不能为空")
        private Integer status;
    }
} 